#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <ctype.h>
#include <stdbool.h>
#include <unistd.h>

#define MAX_DISHES 100
#define MAX_DINERS 1000
#define MAX_TABLES 100
#define MAX_ORDER_ITEMS 50
#define DISH_FILE "dishes.dat"
#define DINER_FILE "diners.dat"
#define TABLE_FILE "tables.dat"
#define COUNTER_FILE "counter.dat"


void save_dishes();
void load_dishes();
void save_tables();
void load_tables();
void save_counter();
void load_counter();
void save_diners();
void load_diners();
int table_exists(int number);
int is_valid_phone(const char *phone);
void get_current_datetime(char *buffer);
void show_menu();

typedef struct {
    int id;
    char name[50];
    char category[50];
    float price;
    char description[100]; // 新增简介字段
} Dish;

typedef struct {
    int dish_id;
    int quantity;
} OrderItem;

typedef struct {
    long long id;
    int table_number;
    char phone[12];
    char name[50];
    OrderItem orders[MAX_ORDER_ITEMS];
    int order_count;
    char datetime[20];
    int status;
    float total_amount;
    bool paid;
} Diner;

typedef struct {
    int number;
    int capacity; // 新增就餐人数字段
    bool available;
} Table;

// 全局变量
Dish dishes[MAX_DISHES];
int dish_count = 0;
Table tables[MAX_TABLES];
int table_count = 0;
Diner diners[MAX_DINERS];
int diner_count = 0;
long long next_diner_id = 1000000000;

// 函数声明
void admin_mode(void);
void manage_dishes(void);
void manage_tables(void);
void user_mode(void);
void setM();
void setDT();
void adminS();
void adminT();
void userREG();
void userOR();
void userPB();
void query_diners(void);
void show_statistics(void);

// 新增辅助函数
float calculate_total(const Diner *diner);
void print_receipt(const Diner *diner);
int find_dish_index(int dish_id);
int find_table_index(int table_num);
int find_diner_index(const char *phone, int table_num);

int main(int argc, char *argv[]) {
    // 初始化文件检测
    if (_access(DISH_FILE, F_OK) == -1) save_dishes();
    if (_access(TABLE_FILE, F_OK) == -1) save_tables();
    if (_access(COUNTER_FILE, F_OK) == -1) save_counter();

    if (argc != 2) {
        printf("Usage: %s -admin|-user\n", argv[0]);
        return 1;
    }

    load_counter();
    load_dishes();
    load_tables();
    load_diners();

    if (strcmp(argv[1], "-admin") == 0) {
        admin_mode();
    } else if (strcmp(argv[1], "-user") == 0) {
        user_mode();
    } else {
        printf("Invalid user type\n");
        return 1;
    }

    save_dishes();
    save_diners();
    save_tables();
    save_counter();

    // 释放内存
    for (int i = 0; i < diner_count; i++) {
        free(diners[i].orders);
    }

    return 0;
}


// 修改后的管理员菜单
void admin_mode() {
    int choice;
    do {
        printf("\nAdmin Menu\n");
        printf("1. 菜品管理\n");
        printf("2. 餐桌管理\n");
        printf("3. 综合查询\n");
        printf("4. 统计报表\n");
        printf("0. 退出\n");
        printf("选择: ");
        scanf("%d", &choice);

        switch (choice) {
            case 1: setM(); break;
            case 2: setDT(); break;
            case 3: adminS(); break;
            case 4: adminT(); break;
        }
    } while (choice != 0);
}

// 菜品管理函数实现
void setM() {
    int choice;
    do {
        printf("\n菜品管理\n");
        printf("1. 添加菜品\n");
        printf("2. 修改菜品\n");
        printf("3. 删除菜品\n");
        printf("4. 查询菜品\n");
        printf("0. 返回\n");
        printf("选择: ");
        scanf("%d", &choice);

        switch (choice) {
            case 1: {
                Dish new_dish;
                printf("菜品编号: ");
                scanf("%d", &new_dish.id);
                printf("菜品名称: ");
                scanf("%s", new_dish.name);
                printf("菜品类别: ");
                scanf("%s", new_dish.category);
                printf("价格: ");
                scanf("%f", &new_dish.price);
                printf("简介: ");
                scanf("%s", new_dish.description);
                dishes[dish_count++] = new_dish;
                save_dishes();
                break;
            }
            case 2: {
                int id;
                printf("输入要修改的菜品编号: ");
                scanf("%d", &id);
                int index = find_dish_index(id);
                if (index != -1) {
                    printf("新名称: ");
                    scanf("%s", dishes[index].name);
                    printf("新价格: ");
                    scanf("%f", &dishes[index].price);
                    save_dishes();
                } else {
                    printf("菜品不存在!\n");
                }
                break;
            }
            case 3: {
                int id;
                printf("输入要删除的菜品编号: ");
                scanf("%d", &id);
                int index = find_dish_index(id);
                if (index != -1) {
                    for (int i = index; i < dish_count-1; i++) {
                        dishes[i] = dishes[i+1];
                    }
                    dish_count--;
                    save_dishes();
                }
                break;
            }
            case 4: {
                printf("\n%-5s %-20s %-15s %-10s %s\n", 
                      "ID", "Name", "Category", "Price", "Description");
                for (int i = 0; i < dish_count; i++) {
                    printf("%-5d %-20s %-15s %-10.2f %s\n",
                           dishes[i].id, dishes[i].name,
                           dishes[i].category, dishes[i].price,
                           dishes[i].description);
                }
                break;
            }
        }
    } while (choice != 0);
}

// 餐桌管理函数实现
void setDT() {
    int choice;
    do {
        printf("\n餐桌管理\n");
        printf("1. 添加餐桌\n");
        printf("2. 修改餐桌\n");
        printf("3. 删除餐桌\n");
        printf("4. 查询餐桌\n");
        printf("0. 返回\n");
        printf("选择: ");
        scanf("%d", &choice);

        switch (choice) {
            case 1: {
                Table new_table;
                printf("桌号: ");
                scanf("%d", &new_table.number);
                printf("容量: ");
                scanf("%d", &new_table.capacity);
                new_table.available = true;
                tables[table_count++] = new_table;
                save_tables();
                break;
            }
            case 2: {
                int num;
                printf("输入要修改的桌号: ");
                scanf("%d", &num);
                int index = find_table_index(num);
                if (index != -1) {
                    printf("新容量: ");
                    scanf("%d", &tables[index].capacity);
                    save_tables();
                }
                break;
            }
        }
    } while (choice != 0);
}

// 管理员查询功能实现
void adminS() {
    int choice;
    printf("\n查询条件:\n");
    printf("1. 按菜品查询\n2. 按桌号查询\n3. 按电话查询\n4. 按姓名查询\n5. 按日期查询\n选择: ");
    scanf("%d", &choice);
    
    char query[50];
    switch(choice) {
        case 1: {
            printf("输入菜品ID: ");
            int dish_id;
            scanf("%d", &dish_id);
            printf("\n订单记录:\n");
            for (int i = 0; i < diner_count; i++) {
                for (int j = 0; j < diners[i].order_count; j++) {
                    if (diners[i].orders[j].dish_id == dish_id) {
                        printf("桌号:%d 数量:%d 时间:%s\n",
                              diners[i].table_number,
                              diners[i].orders[j].quantity,
                              diners[i].datetime);
                    }
                }
            }
            break;
        }
        case 3: {
            printf("输入电话号码: ");
            scanf("%s", query);
            for (int i = 0; i < diner_count; i++) {
                if (strcmp(diners[i].phone, query) == 0) {
                    print_receipt(&diners[i]);
                }
            }
            break;
        }
        // 其他查询条件类似实现
    }
}

// 统计功能实现
void adminT() {
    char date[11];
    printf("输入日期(YYYY-MM-DD): ");
    scanf("%s", date);
    
    float daily_total = 0;
    int dish_counts[MAX_DISHES] = {0};
    
    for (int i = 0; i < diner_count; i++) {
        if (strncmp(diners[i].datetime, date, 10) == 0) {
            daily_total += diners[i].total_amount;
            for (int j = 0; j < diners[i].order_count; j++) {
                int dish_id = diners[i].orders[j].dish_id;
                int index = find_dish_index(dish_id);
                if (index != -1) {
                    dish_counts[index] += diners[i].orders[j].quantity;
                }
            }
        }
    }
    
    printf("\n当日营业额: %.2f\n", daily_total);
    printf("热销菜品TOP10:\n");
    // 排序并输出前10名
}

// 用户注册功能
void userREG() {
    Diner new_diner;
    printf("桌号: ");
    scanf("%d", &new_diner.table_number);
    
    if (!table_exists(new_diner.table_number)) {
        printf("无效桌号!\n");
        return;
    }

    printf("电话: ");
    scanf("%s", new_diner.phone);
    if (!is_valid_phone(new_diner.phone)) {
        printf("无效电话号码!\n");
        return;
    }

    printf("姓名: ");
    scanf("%s", new_diner.name);

    new_diner.id = next_diner_id++;
    get_current_datetime(new_diner.datetime);
    new_diner.order_count = 0;
    new_diner.paid = false;
    
    diners[diner_count++] = new_diner;
}

// 用户点餐功能
void userOR() {
    int table_num;
    char phone[12];
    printf("输入桌号: ");
    scanf("%d", &table_num);
    printf("输入电话: ");
    scanf("%s", phone);
    
    int index = find_diner_index(phone, table_num);
    if (index == -1) {
        printf("未找到订单记录!\n");
        return;
    }
    
    show_menu();
    
    int dish_id, qty;
    do {
        printf("输入菜品ID和数量 (0结束): ");
        scanf("%d", &dish_id);
        if (dish_id == 0) break;
        scanf("%d", &qty);
        
        if (find_dish_index(dish_id) == -1) {
            printf("无效菜品ID!\n");
            continue;
        }
        
        diners[index].orders[diners[index].order_count].dish_id = dish_id;
        diners[index].orders[diners[index].order_count].quantity = qty;
        diners[index].order_count++;
    } while(1);
    
    diners[index].total_amount = calculate_total(&diners[index]);
}

// 结账功能
void userPB() {
    int table_num;
    char phone[12];
    printf("输入桌号: ");
    scanf("%d", &table_num);
    printf("输入电话: ");
    scanf("%s", phone);
    
    int index = find_diner_index(phone, table_num);
    if (index == -1) {
        printf("未找到订单记录!\n");
        return;
    }
    
    print_receipt(&diners[index]);
    
    printf("确认支付? (Y/N): ");
    char confirm;
    scanf(" %c", &confirm);
    if (toupper(confirm) == 'Y') {
        diners[index].paid = true;
        tables[find_table_index(table_num)].available = true;
        printf("支付成功!\n");
    }
}

// 辅助函数实现
float calculate_total(const Diner *diner) {
    float total = 0;
    for (int i = 0; i < diner->order_count; i++) {
        int dish_index = find_dish_index(diner->orders[i].dish_id);
        if (dish_index != -1) {
            total += dishes[dish_index].price * diner->orders[i].quantity;
        }
    }
    return total;
}

void print_receipt(const Diner *diner) {
    printf("\n=== 消费凭据 ===\n");
    printf("桌号: %d\n", diner->table_number);
    printf("姓名: %s\n", diner->name);
    printf("电话: %s\n", diner->phone);
    printf("时间: %s\n", diner->datetime);
    printf("----------------\n");
    
    for (int i = 0; i < diner->order_count; i++) {
        int dish_index = find_dish_index(diner->orders[i].dish_id);
        printf("%-20s x%d ￥%.2f\n", 
              dishes[dish_index].name,
              diner->orders[i].quantity,
              dishes[dish_index].price * diner->orders[i].quantity);
    }
    printf("----------------\n");
    printf("总金额: ￥%.2f\n", diner->total_amount);
    printf("================\n");
}

// 文件保存/加载函数
void save_dishes() {
    FILE *file = fopen(DISH_FILE, "wb");
    if (file) {
        fwrite(&dish_count, sizeof(int), 1, file);
        fwrite(dishes, sizeof(Dish), dish_count, file);
        fclose(file);
    }
}

void load_dishes() {
    FILE *file = fopen(DISH_FILE, "rb");
    if (file) {
        fread(&dish_count, sizeof(int), 1, file);
        fread(dishes, sizeof(Dish), dish_count, file);
        fclose(file);
    }
}

void save_tables() {
    FILE *file = fopen(TABLE_FILE, "wb");
    if (file) {
        fwrite(&table_count, sizeof(int), 1, file);
        fwrite(tables, sizeof(Table), table_count, file);
        fclose(file);
    }
}

void load_tables() {
    FILE *file = fopen(TABLE_FILE, "rb");
    if (file) {
        fread(&table_count, sizeof(int), 1, file);
        fread(tables, sizeof(Table), table_count, file);
        fclose(file);
    }
}

// 餐桌存在性检查
int table_exists(int number) {
    for (int i = 0; i < table_count; i++) {
        if (tables[i].number == number) {
            return 1;
        }
    }
    return 0;
}

// 电话号码验证
int is_valid_phone(const char *phone) {
    if (strlen(phone) != 11) return 0;
    for (int i = 0; i < 11; i++) {
        if (!isdigit(phone[i])) return 0;
    }
    return 1;
}

// 获取当前时间
void get_current_datetime(char *buffer) {
    time_t now = time(NULL);
    struct tm *t = localtime(&now);
    strftime(buffer, 20, "%Y-%m-%d %H:%M", t);
}

// 显示菜单
void show_menu() {
    printf("\n=== 菜单 ===\n");
    printf("%-5s %-20s %-15s %-10s %s\n", 
          "ID", "名称", "类别", "价格", "简介");
    for (int i = 0; i < dish_count; i++) {
        printf("%-5d %-20s %-15s ￥%-9.2f %s\n",
              dishes[i].id, dishes[i].name,
              dishes[i].category, dishes[i].price,
              dishes[i].description);
    }
    printf("================\n");
}

// 补充计数器文件操作
void save_counter() {
    FILE *file = fopen(COUNTER_FILE, "wb");
    if (file) {
        fwrite(&next_diner_id, sizeof(long long), 1, file);
        fclose(file);
    }
}

void load_counter() {
    FILE *file = fopen(COUNTER_FILE, "rb");
    if (file) {
        fread(&next_diner_id, sizeof(long long), 1, file);
        fclose(file);
    }
}

// 补充查找函数
int find_dish_index(int dish_id) {
    for (int i = 0; i < dish_count; i++) {
        if (dishes[i].id == dish_id) {
            return i;
        }
    }
    return -1;
}

int find_table_index(int table_num) {
    for (int i = 0; i < table_count; i++) {
        if (tables[i].number == table_num) {
            return i;
        }
    }
    return -1;
}

int find_diner_index(const char *phone, int table_num) {
    for (int i = 0; i < diner_count; i++) {
        if (strcmp(diners[i].phone, phone) == 0 && 
            diners[i].table_number == table_num) {
            return i;
        }
    }
    return -1;
}